local monsters = {}
local MONSTER_GEN_SPACE = 1073811571

---类型声明
do
    ---@class maxmincount
    ---@field min integer 最小数量
    ---@field max integer 最大数量

    ---@class monsterGroup 怪物组单元
    ---@field presetKey integer 怪物预设ID
    ---@field name string 怪物名称
    ---@field count integer | maxmincount 生成数量

    ---@alias genType string | "'单体'" | "'群组'" | "'BOSS'" 生成类型

    ---@class monsterTable 怪物配置表
    ---@field genType genType 生成类型
    ---@field rebornTime number 重生时间
    ---@field autoReborn boolean 是否自动重生
    ---@field maxAmount integer 最大生成数量
    ---@field presetKey integer 怪物预设ID
    ---@field name string 怪物名称
    ---@field groups monsterGroup[] 怪物组集

    ---@class Monster
    ---@field ctrl_unit Creature
    ---@field group_unit monsterGroupUnit 所属怪物群组单元
    ---@field group_unit_order integer 怪物群组单元编号
    ---@field group_unit_state integer 怪物群组单元状态
end

---怪物群组单元
do
    ---怪物群组单元
    ---@class monsterGroupUnit
    ---@field members Monster[] 群组成员
    ---@field name string 群组名称
    ---@field rebornTime number
    monsterGroupUnit = {}
    monsterGroupUnit.__index = monsterGroupUnit

    ---怪物群组单元构造函数
    ---@param name string
    ---@return monsterGroupUnit
    function monsterGroupUnit.new(name)
        local self = setmetatable({}, monsterGroupUnit)
        self.name = name
        self.members = {}
        return self
    end

    ---怪物群组单元追加方法
    ---@param unit Monster
    function monsterGroupUnit:append(unit)
        table.insert(self.members, unit)
    end

    ---群组怪物死亡
    ---@param unit Monster
    function monsterGroupUnit:die(unit)
        unit.group_unit_state = 0
        for _, _unit in pairs(self.members) do
            if _unit.group_unit_state ~= 0 then
                return
            end
        end
        self:reborn()
    end

    ---群组怪物复活
    function monsterGroupUnit:reborn()
        LuaAPI.call_delay_time(
            self.rebornTime,
            function()
                for _, monster in pairs(self.members) do
                    LuaAPI.global_send_event(
                        { EVENT.CUSTOM_EVENT, "复活" },
                        {
                            ["复活者"] = monster.ctrl_unit
                        }
                    )
                end
            end
        )
    end
end



---@param monsterTable monsterTable
function RegisterUnit(monsterTable)
    local genType = monsterTable.genType
    local function create_creature(presetKey)
        return GameAPI.create_creature(
            presetKey,
            math.Vector3(0, 100, 0),
            math.Quaternion(0, 0, 0),
            math.Vector3(0, 0, 0)
        )
    end
    ---配置出生点
    local custom_space_list = LuaAPI.query_units_by_type(Enums.UnitType.CUSTOMTRIGGERSPACE, 1073811571) ---@type CustomTriggerSpace[]
    local position = custom_space_list[GameAPI.random_int(1, #custom_space_list)].random_point()
    position.y = position.y + math.tofixed(20)
    if genType == '单体' then
        LuaAPI.unit_register_creation_handler(
            Enums.UnitType.CREATURE, monsterTable.presetKey,
            function(actor)
                ---传递生成类型
                actor.set_kv_by_type(Enums.ValueType.Str, "生成类型", genType)
                MonsterEvent(actor, monsterTable)

                ---设置出生点
                actor.set_kv_by_type(Enums.ValueType.Vector3, "出生点", position)
                actor.set_position(position)
            end
        )
        create_creature(monsterTable.presetKey)
    elseif genType == '群组' then
        ---初始化群组单元
        local group_unit = monsterGroupUnit.new(monsterTable.name)
        group_unit.rebornTime = monsterTable.rebornTime

        for _, monster in ipairs(monsterTable.groups) do
            local count = monster.count
            LuaAPI.unit_register_creation_handler(
                Enums.UnitType.CREATURE, monster.presetKey,
                ---@param actor Creature
                function(actor)
                    ---传递生成类型
                    actor.set_kv_by_type(Enums.ValueType.Str, "生成类型", genType)

                    ---设置出生点
                    actor.set_kv_by_type(Enums.ValueType.Vector3, "出生点", position)
                    actor.set_position(position)

                    ---配置群组单元
                    local _monster = {
                        ctrl_unit = actor,
                        group_unit = group_unit,
                        group_unit_order = #group_unit.members,
                        group_unit_state = 1
                    } ---@type Monster
                    group_unit:append(_monster)
                    actor.set_auto_reborn_enabled(false)
                    MonsterEvent(actor, monster, _monster)
                end
            )

            if type(count) ~= "number" then
                count = GameAPI.random_int(count.min, count.max)
            end

            for _ = 1, count do
                create_creature(monster.presetKey)
            end
        end
    end
end

---任意怪蛋通用事件注册
---@param actor Creature
---@param config monsterTable | monsterGroup
---@param _monster? Monster
function MonsterEvent(actor, config, _monster)
    ---如果有rebornTime就允许重生
    if rawget(config, "genType") and config.autoReborn then
        actor.set_auto_reborn_enabled(true)
        actor.set_infinite_reborn_enabled(true)
        actor.set_reborn_time(math.tofixed(config.rebornTime))
    elseif rawget(config, "genType") then
        actor.set_auto_reborn_enabled(false)
    end
    
    ---设置名称
    actor.set_name(config.name)
    actor.set_name_visible(true)

    ---注册事件
    LuaAPI.unit_register_trigger_event(actor, { EVENT.SPEC_LIFEENTITY_DIE }, function ()
        if (actor.get_kv_by_type(Enums.ValueType.Str, "生成类型") == "群组") and (_monster ~= nil) then
            _monster.group_unit:die(_monster)
        end
    end)
end

---根据配置注册怪物
---@param name string 配置名
function monsters.Import(name)
    if GlobalAPI.str_contains(name, "_type") then
        GlobalAPI.error("错误的配置文件<_type>")
        return
    end
    local ok, data = pcall(require, "monster@" .. name)
    if not ok then
        GlobalAPI.error(string.format("错误的配置文件<%s>", name))
        return
    end
    local _monsters = data.monsters ---@type monsterTable[]

    for _, monsterTable in ipairs(_monsters) do
        RegisterUnit(monsterTable)
    end
end

return monsters
